'use strict';

const BaseService = require('../base');
const { OrderStatusEnum, OrderPaymentEnum} = require('../../utils/enum');
const dayjs = require('dayjs');
const { Op,literal } = require('sequelize');
const { v1: uuidv4 } = require('uuid');
const QRCode = require('qrcode');
/**
 * 生成订单号
 * @return {string}
 */
function generateOrderNo() {
    const now = dayjs();
    // 生成格式：年月日时分秒+4位随机数
    return 'ON' + now.format('YYYYMMDDHHmmss') + Math.floor(Math.random() * 10000).toString().padStart(4, '0');
}

class OrderService extends BaseService {
    static get modelName() {
        return 'Business.Order';
    }
    getPageInclude() {
        return [
            {
                model: this.ctx.model.Business.User,
                as: 'user',
            },
            {
                model: this.ctx.model.Business.OrderItem,
                as: 'items'
            },
            {
                model: this.ctx.model.Business.Comment,
                as: 'comments'
            },
            {
                model: this.ctx.model.Business.OrderCode,
                as: 'codes',
                where: {
                    status: 1
                },
                required: false,
            }
            // {
            //     model: this.ctx.model.Business.UserCoupon,
            //     as: 'userCoupon',
            //     include: [
            //         {
            //             model: this.ctx.model.Business.Coupon,
            //             as: 'coupon'
            //         }
            //     ]
            // }
        ]
    }
    getDetailInclude() {
        return this.getPageInclude()
    }
    /**
     * 创建订单
     * @param {Object} orderData - 订单数据
     * @return {Promise<*>}
     */
    async create(orderData) {
        const { ctx } = this;
        /**
         * 校验用户
         */
        if (!orderData.user_id) throw new Error('用户不存在');
        // 检查用户是否存在
        const user = await ctx.model.Business.User.findOne({
            where: {
                id: orderData.user_id
            }
        })
        if (!user) {
            throw new Error('用户不存在');
        }
        if (!user.status) {
            throw new Error('用户已禁用');
        }
        /**
         * 校验产品
         */
        // 检查产品是否存在
        const product = await ctx.model.Business.Product.findAll({
            where: {
                id: {
                    [Op.in]: orderData.goods.map(item => item.id),
                },
                status: 1
            }
        })
        if (!product || !product.length) throw new Error('产品不存在');
        if (product.length !== orderData.goods.length) throw new Error('有下架产品');
        // 创建订单
        // 订单事务
        const transaction = await ctx.model.transaction();
        try {
            // 1. 生成订单号
            const orderNo = generateOrderNo();
            // 2. 创建主订单
            const createData = {
                order_no: orderNo,
                ...orderData,
                // 产品快照
                product_detail: JSON.stringify(orderData.goods),
                parent_user_id: user.parent_user_id || 0
            }
            if (!createData.payment_amount || createData.payment_amount == 0) {
                createData.status = OrderStatusEnum.PENDING_VERIFICATION
            }
            // 3. 扣减产品库存
            for (let i = 0; i < orderData.goods.length; i++) {
                const goodsItem = orderData.goods[i];
                const _product = await this.ctx.model.Business.Product.findOne({ where: { id: goodsItem.id } });
                if (_product) {
                    // 使用 decrement 方法减少库存
                    await _product.decrement('stock', { by: goodsItem.count, transaction });
                }
            }
            // 4. 创建订单
            const order = await ctx.model.Business.Order.create(createData, { transaction });
            console.log('创建订单',order)
            // 失效优惠券，绑定订单id
            // 扣减余额
            if (orderData.discount_coupon_id && orderData.discount_coupon_id > 0) {
                // 查找用户优惠券
                const userCoupon = await this.ctx.model.Business.UserCoupon.findOne({
                    where: {
                        user_id: user.id,
                        id: orderData.discount_coupon_id,
                        status: 0, // 未使用
                    },
                    include: [{
                        model: this.ctx.model.Business.Coupon,
                        as: 'coupon'
                    }],
                    transaction
                });

                if (!userCoupon) {
                    throw new Error('优惠券不存在或已使用');
                }

                // 验证优惠券是否过期
                if (new Date() > new Date(userCoupon.expire_time)) {
                    throw new Error('优惠券已过期');
                }

                // 验证优惠券使用条件
                const coupon = userCoupon.coupon;
                if (coupon.min_amount && orderData.amount < coupon.min_amount) {
                    throw new Error(`订单金额不足，需要满${coupon.min_amount}元才能使用`);
                }

                // 失效优惠券，绑定订单
                await userCoupon.update({
                    status: 1, // 已使用
                    order_id: order.id,
                    use_time: new Date()
                }, { transaction });
            }

            // 扣减余额
            if (orderData.balance_deduct && orderData.balance_deduct > 0) {
                // 验证用户余额是否足够
                if (user.balance < orderData.balance_deduct) {
                    throw new Error('用户余额不足');
                }

                // 扣减用户余额
                await this.ctx.model.Business.User.update({
                    balance: this.ctx.model.Sequelize.literal(`balance - ${orderData.balance_deduct}`)
                }, {
                    where: { id: user.id },
                    transaction
                });

                // 创建余额扣减记录
                await this.ctx.model.Business.BalanceRecord.create({
                    user_id: user.id,
                    user_type: user.user_type,
                    amount: -orderData.balance_deduct, // 负数表示扣减
                    type: 3, // 3 表示订单扣减
                    description: `订单${orderNo}余额抵扣`
                }, { transaction });
            }

             // 5. 批量创建子订单
            let orderCodeList = []
            for (let orderItem = 0; orderItem < orderData.goods.length; orderItem++) {
                let item = orderData.goods[orderItem];
                const goodsRes = await ctx.model.Business.OrderItem.create({
                    shop_user_id: order.shop_user_id || 0,
                    order_id: order.id,
                    order_no: orderNo,
                    user_id: orderData.user_id,
                    product_id: item.id,
                    count: item.count,
                    product_detail: JSON.stringify(item),
                }, {
                    transaction
                })
                let orderItemId = goodsRes.id
                if (item.children && item.children.length) {
                    // 子商品核销
                    for (let i = 0; i < item.children.length; i++) {
                        for (let j = 0; j < item.count; j++) {
                            let code = uuidv4().replace(/-/g, '').substring(0, 8);
                            let code_url = await QRCode.toDataURL(code);
                            orderCodeList.push({
                                code,
                                code_url,
                                shop_user_id: order.shop_user_id || 0,
                                order_no: orderNo,
                                order_id: order.id,
                                order_item_id: orderItemId,
                                user_id: orderData.user_id,
                                product_id: item.children[i].id,
                                product_name: item.children[i].title,
                                parent_product_id: item.id,
                                parent_product_name: item.title,
                                product_detail: JSON.stringify(item),
                                product_price: item.children[i].price,
                                rebate_price: item.children[i].rebate_price,
                                rebate_price_platform: item.children[i].rebate_price_platform,
                                rebate_price_shop: item.children[i].rebate_price_shop,
                                rebate_price_agent: item.children[i].rebate_price_agent,
                                rebate_price_agent2: item.children[i].rebate_price_agent2,
                                rebate_price_platform_percent: item.children[i].rebate_price_platform_percent,
                                rebate_price_shop_percent: item.children[i].rebate_price_shop_percent,
                                rebate_price_agent_percent: item.children[i].rebate_price_agent_percent,
                                rebate_price_agent_percent2: item.children[i].rebate_price_agent_percent2,
                            })
                        }
                    }
                } else {
                    let code = uuidv4().replace(/-/g, '').substring(0, 8);
                    let code_url = await QRCode.toDataURL(code);
                    orderCodeList.push({
                        shop_user_id: order.shop_user_id || 0,
                        code,
                        code_url,
                        order_id: order.id,
                        order_no: orderNo,
                        order_item_id: orderItemId,
                        user_id: orderData.user_id,
                        product_id: item.id,
                        parent_product_id: 0,
                        product_name: item.title,
                        parent_product_name: '',
                        product_detail: JSON.stringify(item),
                        product_price: item.price,
                        rebate_price: item.rebate_price,
                        rebate_price_platform: item.rebate_price_platform,
                        rebate_price_shop: item.rebate_price_shop,
                        rebate_price_agent: item.rebate_price_agent,
                        rebate_price_agent2: item.rebate_price_agent2,
                        rebate_price_platform_percent: item.rebate_price_platform_percent,
                        rebate_price_shop_percent: item.rebate_price_shop_percent,
                        rebate_price_agent_percent: item.rebate_price_agent_percent,
                        rebate_price_agent_percent2: item.rebate_price_agent_percent2,
                    })
                }
            }
            // 6. 批量创建核销码
            if (orderCodeList.length) {
                await ctx.model.Business.OrderCode.bulkCreate(orderCodeList, { transaction });
            }
            await transaction.commit();
            // 6. 返回订单信息
            return order
        } catch (error) {
            console.log(error)
            await transaction.rollback();
            throw error;
        }
    }

    /**
     * 取消订单
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async cancel(params) {
        const { ctx } = this;
        const { id } = params;
        const transaction = await ctx.model.transaction();

        try {
            // 1. 查询订单
            const order = await this.ctx.model.Business.Order.findOne({
                where: {
                    id,
                },
            });

            if (!order) {
                throw new Error('订单不存在');
            }
            const user = await this.ctx.model.Business.User.findOne({
                where: {
                    id: order.user_id
                }
            })
            if (!user) {
                throw new Error('用户不存在');
            }
            // 2. 判断订单状态
            if (order.status !== OrderStatusEnum.PENDING_PAYMENT) {
                throw new Error('只有待支付的订单才能取消');
            }

            // 3. 退还优惠券（如果使用了优惠券）
            if (order.discount_coupon_id) {
                await this.ctx.model.Business.UserCoupon.update({
                    status: 0, // 恢复为未使用状态
                    order_id: 0,
                    use_time: null
                }, {
                    where: {
                        user_id: order.user_id,
                        id: order.discount_coupon_id,
                        order_id: order.id
                    },
                    transaction
                });
            }

            // 4. 退还余额（如果使用了余额抵扣）
            if (order.balance_deduct && order.balance_deduct > 0) {
                // 退还用户余额
                await this.ctx.model.Business.User.update({
                    balance: this.ctx.model.Sequelize.literal(`balance + ${order.balance_deduct}`)
                }, {
                    where: { id: order.user_id },
                    transaction
                });

                // 创建余额退还记录
                await this.ctx.model.Business.BalanceRecord.create({
                    user_id: order.user_id,
                    user_type: user.user_type, // 默认为普通用户类型
                    amount: order.balance_deduct, // 正数表示退还
                    type: 4, // 4 表示订单退款
                    description: `订单${order.order_no}取消，余额退还`
                }, { transaction });
            }

            // 5. 更新订单状态
            await order.update({
                status: OrderStatusEnum.CANCELLED,
                cancel_time: new Date(),
            }, { transaction });

            await transaction.commit();
            return true;
        } catch (error) {
            await transaction.rollback();
            throw error;
        }
    }
    /**
     * 获取订单详情
     * @param {Object} params - 参数
     * @return {Promise<Object>}
     */
    async detail(params) {
        const { ctx } = this;
        const { id } = params;

        // 查询订单
        const order = await this.model.findOne({
            where: { id },
            include: [
                {
                    model: ctx.model.Product,
                    as: 'product',
                    attributes: ['id', 'title', 'post_url', 'price']
                }
            ]
        });

        if (!order) {
            throw new Error('订单不存在');
        }

        // 格式化时间
        const result = order.toJSON();
        if (result.time_expire) {
            result.status = OrderStatusEnum.CANCELLED
            // 判断当前是否超过15分钟，超过需要将订单变成取消 dayjs判断
            if (dayjs().diff(dayjs(result.time_expire), 'minute') > 15) {
                await this.cancel({ id });
            }

        } else {
            result.status = OrderStatusEnum.CANCELLED
            await this.cancel({ id });
        }
        return result;
    }

    /**
     * 申请退款
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async refund(params) {
        const { ctx } = this;
        const { id, refund_amount, refund_reason } = params;
        const transaction = await ctx.model.transaction();

        try {
            // 查询订单
            const order = await this.ctx.model.Business.Order.findOne({
                where: { id }
            });

            if (!order) {
                throw new Error('订单不存在');
            }

            // 判断订单状态
            if (order.status !== OrderStatusEnum.PAID && order.status !== OrderStatusEnum.PENDING_VERIFICATION) {
                throw new Error('订单状态不正确：' + order.status + OrderStatusEnum.PENDING_VERIFICATION);
            }
            let refundForm = {
                status: OrderStatusEnum.REFUNDING,
                refund_time: new Date(),
                refund_reason,
                refund_amount: refund_amount || order.payment_amount
            }
            // 更新订单状态
            await order.update(refundForm, { transaction });

            await transaction.commit();
            return true;
        } catch (error) {
            await transaction.rollback();
            throw error;
        }
    }

    /**
     * 处理退款
     */
    async refundConfirm(data) {
        const { id, refund_remark, refund_amount, approve } = data;

        // 查询订单
        const order = await this.ctx.model.Business.Order.findOne({
            where: { id }
        });

        if (!order) {
            throw new Error('订单不存在');
        }
        let refund_amount_int = Number(refund_amount)
        if (!approve) {
            // 不同意退款
            await order.update({
                status: OrderStatusEnum.PENDING_VERIFICATION,
                refund_time: new Date(),
                refund_remark,
            });
            return true
        } else {
            // 同意退款
            if (refund_amount_int >= order.payment_amount) {
                refund_amount_int = order.payment_amount
            }

            // 创建事务处理退款
            const transaction = await this.ctx.model.transaction();

            try {
                await order.update({
                    status: refund_amount_int ? OrderStatusEnum.REFUNDING : OrderStatusEnum.REFUNDED,
                }, { transaction });

                // 退还优惠券（如果使用了优惠券）
                if (order.discount_coupon_id) {
                    await this.ctx.model.Business.UserCoupon.update({
                        status: 0, // 恢复为未使用状态
                        order_id: 0,
                        use_time: null
                    }, {
                        where: {
                            user_id: order.user_id,
                            id: order.discount_coupon_id,
                            order_id: order.id
                        },
                        transaction
                    });
                }

                // 退还余额（如果使用了余额抵扣）
                if (order.balance_deduct && order.balance_deduct > 0) {
                    const user = await this.ctx.model.Business.User.findOne({
                        where: { id: order.user_id }
                    })
                    if (!user) {
                        throw new Error('用户不存在');
                    }
                    // 退还用户余额
                    await this.ctx.model.Business.User.update({
                        balance: this.ctx.model.Sequelize.literal(`balance + ${order.balance_deduct}`)
                    }, {
                        where: { id: order.user_id },
                        transaction
                    });

                    // 创建余额退还记录
                    await this.ctx.model.Business.BalanceRecord.create({
                        user_id: order.user_id,
                        user_type: user.user_type, // 默认为普通用户类型
                        amount: order.balance_deduct, // 正数表示退还
                        type: 4, // 4 表示订单退款
                        description: `订单${order.order_no}退款，余额退还`
                    }, { transaction });
                }
                // 实付满额才退微信支付
                if (refund_amount_int) {
                    // 调用退款接口
                    await this.ctx.service.business.orderRefund.processRefund({
                        order_no: order.order_no,
                        refund_remark,
                        refund_amount: refund_amount_int,
                        payment_amount: order.payment_amount
                    });
                }

                await transaction.commit();
            } catch (e) {
                await transaction.rollback();
                throw e;
            }
        }
        return true
    }

    /**
     * 删除订单
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async delete(id) {
        // 查询订单
        const order = await this.model.findOne({
            where: { id }
        });

        if (!order) {
            throw new Error('订单不存在');
        }

        // 只有已取消、已退款的订单可以删除
        if (![OrderStatusEnum.CANCELLED].includes(order.status)) {
            throw new Error('只有已取消的订单才能删除');
        }
        console.log('删除成功')
        // 软删除订单
        await super.delete(id, 0)
        return true;
    }
}

module.exports = OrderService;
